/*
 * Motor.cpp
 *
 *  Created on: 18/10/2012
 *      Author: Ignacio Galvez
 */
#include "Motor.h"
#include "Pajaro.h"
#include "Bonificable.h"
#include "Caja.h"
#include "Cerdito.h"
#include "Huevo.h"
#include "Jugador.h"
#include "MonticuloDeHuevos.h"
#include "Nivel.h"
#include <cmath>


// Motor::Motor(int numeroNivel, int cantidadDeJugadores, double timeout) :
// 		numeroNivel(numeroNivel), puntajeMaximo(0), puntajeActual(0), cantidadDeJugadores(
// 				cantidadDeJugadores), timeout(timeout), gano(false), perdio(
// 				false), superficie(10, 20), monticuloDeHuevos(NULL) {
// }

Motor::Motor(Nivel& nivel) {}

void Motor::ejecutarColisiones(double t) {
	const double deltaX = .8;
	const double deltaY = .8;
	std::list<Huevo*>::iterator itHuevos;
	std::list<Caja*>::iterator itCajas;
	std::list<Bonificable*>::iterator itBonificables;
	std::list<Pajaro*>::iterator itPajaros;
	std::list<Cerdito*>::iterator itCerditos;
	for (itHuevos = huevos.begin(); itHuevos != huevos.end(); ++itHuevos) {
		for (itCajas = cajas.begin(); itCajas != cajas.end(); ++itCajas) {
			if ((fabs((*itHuevos)->getPosicionX() - (*itCajas)->getPosicionX())
					<= deltaX)
					&& (fabs(
							(*itHuevos)->getPosicionY()
									- (*itCajas)->getPosicionY()) <= deltaY)) 
				puntajeActual += (*itCajas)->bonificar();
				(*itHuevos)->daniar((*itCajas));
				if ((*itCajas)->getPuntosDeVida() == 0) {
					delete *itCajas;
				}
			
		}
		for (itBonificables = bonificables.begin();
				itBonificables != bonificables.end(); ++itBonificables) {
			if ((fabs(
					(*itHuevos)->getPosicionX()
							- (*itBonificables)->getPosicionX()) <= deltaX)
					&& (fabs(
							(*itHuevos)->getPosicionY()
									- (*itBonificables)->getPosicionY())
							<= deltaY)) {
				puntajeActual += (*itBonificables)->bonificar();
				delete *itBonificables;
			}
		}
		for (itPajaros = pajaros.begin(); itPajaros != pajaros.end();
				++itPajaros) {
				(*itHuevos)->daniar((*itPajaros));
				if ((*itPajaros)->getPuntosDeVida() == 0) {
					delete *itPajaros;
				}
			
		}
	}
	for (itPajaros = pajaros.begin(); itPajaros != pajaros.end(); ++itPajaros) {
		if (superficie.recibirImpacto((*itPajaros)->getPosicionX(),
				(*itPajaros)->getPosicionY()))
			(*itPajaros)->rebotar(t);
		for (itCajas = cajas.begin(); itCajas != cajas.end(); ++itCajas) {
			if ((fabs((*itPajaros)->getPosicionX() - (*itCajas)->getPosicionX())
					<= deltaX)
					&& (fabs(
							(*itPajaros)->getPosicionY()
									- (*itCajas)->getPosicionY()) <= deltaY)) {
				(*itPajaros)->daniar((*itCajas));
				delete (*itPajaros);
				pajaros.erase(itPajaros);
				if ((*itCajas)->getPuntosDeVida() == 0) {
					delete *itCajas;
				}
			}
		}
		for (itBonificables = bonificables.begin();
				itBonificables != bonificables.end(); ++itCajas) {
			if ((fabs(
					(*itPajaros)->getPosicionX()
							- (*itBonificables)->getPosicionX()) <= deltaX)
					&& (fabs(
							(*itPajaros)->getPosicionY()
									- (*itBonificables)->getPosicionY())
							<= deltaY)) {
				delete *itBonificables;
			}
		}
		for (itCerditos = cerditos.begin(); itCerditos != cerditos.end();
				++itCerditos) {
			if ((fabs(
					(*itPajaros)->getPosicionX()
							- (*itCerditos)->getPosicionX()) <= deltaX)
					&& (fabs(
							(*itPajaros)->getPosicionY()
									- (*itCerditos)->getPosicionY()) <= deltaY)) {
				(*itPajaros)->daniar((*itCerditos));
			}
		}

	}
}

void Motor::generarPajaros() {
}

void Motor::realizarDisparos() {
	std::list<Huevo*> huevosNuevos;
	std::list<Huevo*>::iterator itHuevosNuevos;
	std::list<Cerdito*>::iterator itCerditos;
	for (itCerditos = cerditos.begin(); itCerditos != cerditos.end();
			++itCerditos) {
		Cerdito::incrementarTiempoActual();
		if ((*itCerditos)->dispara()) {
			huevosNuevos = (*itCerditos)->disparar();
		}
		for (itHuevosNuevos = huevosNuevos.begin();
				itHuevosNuevos != huevosNuevos.end(); ++itHuevosNuevos) {
			huevos.push_front((*itHuevosNuevos));
		}
	}
}

void Motor::actualizarEstado(double t) {
	std::list<Jugador*>::iterator itJugadores;
	std::list<Huevo*>::iterator itHuevos;
	std::list<Pajaro*>::iterator itPajaros;
	generarPajaros();
	realizarDisparos();
	for (itHuevos = huevos.begin(); itHuevos != huevos.end(); ++itHuevos) {
		(*itHuevos)->mover(t);
	}
	for (itPajaros = pajaros.begin(); itPajaros != pajaros.end(); ++itPajaros) {
		(*itPajaros)->mover(t);
	}
	ejecutarColisiones(t);
	eliminarJugadores();
	perdio = (jugadores.empty()) || (monticuloDeHuevos->getPuntosDeVida() == 0);
}

void Motor::iniciar() {
	double tiempoActual = 0;
	while ((tiempoActual < timeout) && (!perdio)) {
		actualizarEstado(tiempoActual);
		tiempoActual++;
	}
}

void Motor::bonificar() {
}

void Motor::eliminarJugadores() {
	std::list<Jugador*>::iterator it;
	for (it = jugadores.begin(); it != jugadores.end(); ++it) {
		if (!(*it)->estaEnJuego()) {
			delete *it;
		}
	}
}



std::list<Pajaro*>  Motor::getPajaros(){
	return pajaros;
}

std::list<Huevo*> Motor:: getHuevos(){
	return huevos;
}

std::list<Cerdito*>  Motor::getCerditos(){
	return cerditos;
}

std::list<Caja*>  Motor::getCajas(){
	return cajas;
}

std::list<Bonificable*>  Motor::getBonificables(){
	return bonificables;
}



Motor::~Motor() {
}



